#include "mystdio.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

MYFILE* myfopen(const char* filename,const char* mode)
{
  int fd = -1;
  if(strcmp(mode,"r") == 0)
    fd = open(filename,O_RDONLY);
  else if(strcmp(mode,"w") == 0)
    fd = open(filename,O_WRONLY | O_TRUNC | O_CREAT,UMASK);
  else if(strcmp(mode,"a") == 0)
    fd = open(filename,O_WRONLY | O_CREAT | O_APPEND,UMASK);
  
  if(fd < 0)
  {
    perror("myfopen");
    return NULL;
  }

  MYFILE* fp = (MYFILE*)malloc(sizeof(MYFILE));
  if(fp == NULL)
  {
    perror("malloc");
    return NULL;
  }
  fp->capacity = SIZE;
  fp->cur = 0;
  fp->fileno = fd;
  fp->flag = ROW_BUFFER; 
  return fp;
}

void _myfflush(MYFILE* fp,int mode)
{
  if(fp == NULL)
      return;
  if(mode == FORCE && fp->cur > 0)
  {
    write(fp->fileno,fp->out_buffer,fp->cur);
    fp->cur = 0;
  }
  else if(mode == NORMAL && fp->cur > 0)
  {
    if(mode & NO_BUFFER)
    {
      write(fp->fileno,fp->out_buffer,fp->cur);
      fp->cur = 0;
    }
    else if((mode & ROW_BUFFER) && fp->out_buffer[fp->cur - 1] == '\n')
    {
      write(fp->fileno,fp->out_buffer,fp->cur);
      fp->cur = 0;
    }
    else if(fp->cur >= fp->capacity)
    {
      write(fp->fileno,fp->out_buffer,fp->cur);
      fp->cur = 0;
    }
  }
}

int myfwrite(const void* ptr,int size,int n,MYFILE* fp)
{
  //向语言级缓冲区中写入
  int byte_sum = size * n;
  const char* buffer = (char*)ptr;
  for(int i = 0;i < byte_sum;i++)
  {
    fp->out_buffer[fp->cur++] = buffer[i];
    _myfflush(fp,NORMAL);
  }
    return byte_sum;
}

void myfflush(MYFILE* fp)
{
  //从语言级缓冲区向文件内核缓冲区写入
  _myfflush(fp,FORCE);
}

void myfclose(MYFILE* fp)
{
  if(fp == NULL)
  {
    return;
  }
  myfflush(fp);
  close(fp->fileno);
  free(fp);
}
